# coding = utf-8
from building.models import Project, BidType, Category, Document, Archive, DocType, BidBusiness, Deposit, \
    ProjectFinance, FundsDetail, BidInspector, BidDocument
from django.db.models import Sum
from rest_framework import serializers

from rest_framework.serializers import ModelSerializer
# from rest_framework.validators import UniqueTogetherValidator, UniqueValidator


class ProjectSerializer(ModelSerializer):
    """
    工程登记表
    """
    bid_type_name = serializers.CharField(source="bid_type.name", read_only=True)
    category_name = serializers.CharField(source="category.name", read_only=True)
    is_win_name = serializers.CharField(source="get_is_win_display", read_only=True)
    finish_name = serializers.CharField(source="get_finish_display", read_only=True)
    user_name = serializers.CharField(source="user.real_name", read_only=True)

    class Meta:
        model = Project
        exclude = ["update_time", "add_time"]


class ArchiveListSerializer(ModelSerializer):
    """
    工程档案
    """

    class Meta:
        model = Archive
        fields = ["id", "project_id", "project_name", "costs", "duty_man"]


class ProjectListSerializer(ModelSerializer):
    """
    工程登记表
    """
    archive = serializers.SerializerMethodField()

    class Meta:
        model = Project
        fields = ["id", "name", "archive"]

    def get_archive(self, obj):
        instance = obj.archives.first()
        serializer = ArchiveListSerializer(instance=instance)
        return serializer.data


class ProjectSearchSerializer(ModelSerializer):
    """
    工程名称搜索
    """
    value = serializers.CharField(source='name', read_only=True)

    class Meta:
        model = Project
        fields = ["id", "name", "value"]


class BidTypeSerializer(ModelSerializer):
    """
    标书类型
    """
    class Meta:
        model = BidType
        exclude = ["update_time", "add_time"]


class CategorySerializer(ModelSerializer):
    """
    工程类型
    """
    class Meta:
        model = Category
        exclude = ["update_time", "add_time"]


class DocTypeSerializer(ModelSerializer):
    """
    资料类型
    """
    class Meta:
        model = DocType
        exclude = ["update_time", "add_time"]


class DocumentSerializer(ModelSerializer):
    """
    档案资料内容
    """
    doc_type_name = serializers.CharField(source='doc_type.name', read_only=True)

    class Meta:
        model = Document
        fields = [
            "id", "archive", "doc_type", "doc_type_name", "content", "name"
        ]


class ArchiveSerializer(ModelSerializer):
    """
    工程档案
    """
    category_name = serializers.CharField(source="category.name", read_only=True)
    architect = serializers.CharField(source="project.architect", read_only=True)
    is_bid_name = serializers.CharField(source="get_is_bid_display", read_only=True)
    finish_name = serializers.CharField(source="get_finish_display", read_only=True)
    documents = DocumentSerializer(many=True, read_only=True)

    class Meta:
        model = Archive
        exclude = ["update_time", "add_time"]


class DepositSerializer(ModelSerializer):
    """
    保证金
    """
    project_name = serializers.CharField(source="project.name", read_only=True)
    user_name = serializers.CharField(source="user.real_name", read_only=True)

    class Meta:
        model = Deposit
        exclude = ["update_time", "add_time"]


class BidInspectorSerializer(ModelSerializer):
    """
    检查人员
    """
    id = serializers.IntegerField(required=False)
    category_name = serializers.CharField(source='get_category_display', read_only=True)

    class Meta:
        model = BidInspector
        exclude = ["update_time", "add_time"]


class BidDocumentSerializer(ModelSerializer):
    """
    检查人员
    """
    doc_type_name = serializers.CharField(source='get_doc_type_display', read_only=True)

    class Meta:
        model = BidDocument
        exclude = ["update_time", "add_time"]


class BidBusinessSerializer(ModelSerializer):
    """
    保证金
    """
    bid_type_name = serializers.CharField(source="bid_type.name", read_only=True)
    user_name = serializers.CharField(source="user.real_name", read_only=True)
    documents = BidDocumentSerializer(many=True, read_only=True)
    inspectors = BidInspectorSerializer(many=True)

    class Meta:
        model = BidBusiness
        exclude = ["update_time", "add_time"]

    def create(self, validated_data):
        inspectors = validated_data.pop('inspectors')
        instance = self.Meta.model.objects.create(**validated_data)

        data_list = []
        for inspector in inspectors:
            inst = BidInspector(bid=instance, **inspector)
            data_list.append(inst)

        BidInspector.objects.bulk_create(data_list)
        return instance

    def update(self, instance, validated_data):
        inspectors = validated_data.pop('inspectors')
        instance.id = validated_data.get('id', instance.id)
        instance.project = validated_data.get('project', instance.project)
        instance.bid_type = validated_data.get('bid_type', instance.bid_type)
        instance.amount = validated_data.get('amount', instance.amount)

        instance.fees = validated_data.get('fees', instance.fees)
        instance.manager = validated_data.get('manager', instance.manager)
        instance.broker = validated_data.get('broker', instance.broker)
        instance.broker_fees = validated_data.get('broker_fees', instance.broker_fees)
        instance.persons = validated_data.get('persons', instance.persons)
        instance.remark = validated_data.get('remark', instance.remark)
        instance.user = validated_data.get('user', instance.user)
        instance.save()

        for inspector in inspectors:
            detail_id = inspector.pop("id", None)
            if detail_id:
                BidInspector.objects.update_or_create(id=detail_id, defaults=inspector)
            else:
                BidInspector.objects.create(bid=instance, **inspector)

        return instance


class FundsDetailSerializer(ModelSerializer):
    """
    工程款收入支出明细
    """
    id = serializers.IntegerField(required=False)
    fund_class_name = serializers.CharField(source='get_fund_class_display', read_only=True)

    class Meta:
        model = FundsDetail
        exclude = ["update_time", "add_time"]


class ProjectFinanceSerializer(ModelSerializer):
    """
    工程项目财务综合统计
    """
    project_name = serializers.CharField(source="project.name", read_only=True)
    # bill_name = serializers.CharField(source="get_bill_display", read_only=True)
    # checkout_name = serializers.CharField(source="get_checkout_display", read_only=True)
    receive_money = serializers.SerializerMethodField(read_only=True)
    pay_money = serializers.SerializerMethodField(read_only=True)
    details = FundsDetailSerializer(many=True)

    class Meta:
        model = ProjectFinance
        exclude = ["update_time", "add_time"]

    def get_receive_money(self, obj):
        ret = obj.details.filter(fund_class=0).aggregate(recv_money=Sum('money'))
        return ret.get("recv_money", None)

    def get_pay_money(self, obj):
        ret = obj.details.filter(fund_class=1).aggregate(pay_money=Sum('money'))
        return ret.get("pay_money", None)

    def create(self, validated_data):
        details_data = validated_data.pop('details')
        instance = self.Meta.model.objects.create(**validated_data)

        data_list = []
        for detail_data in details_data:
            fund = FundsDetail(finance=instance, **detail_data)
            data_list.append(fund)

        FundsDetail.objects.bulk_create(data_list)
        return instance

    def update(self, instance, validated_data):
        # details_data = self.context["request"].data.get("details", None)
        details_data = validated_data.pop('details')
        instance.id = validated_data.get('id', instance.id)
        instance.project = validated_data.get('project', instance.project)
        instance.company = validated_data.get('company', instance.company)
        instance.contract_accounts = validated_data.get('contract_accounts', instance.contract_accounts)
        # instance.balance_accounts = validated_data.get('balance_accounts', instance.balance_accounts)
        # instance.bill = validated_data.get('bill', instance.bill)
        # instance.checkout = validated_data.get('checkout', instance.checkout)
        instance.former_bill = validated_data.get('former_bill', instance.former_bill)
        instance.current_bill = validated_data.get('current_bill', instance.current_bill)
        instance.remark = validated_data.get('remark', instance.remark)
        instance.manager = validated_data.get('manager', instance.manager)
        instance.telephone = validated_data.get('telephone', instance.telephone)
        instance.user = validated_data.get('user', instance.user)
        instance.save()

        for detail in details_data:
            detail_id = detail.pop("id", None)
            if detail_id:
                FundsDetail.objects.update_or_create(id=detail_id, defaults=detail)
            else:
                FundsDetail.objects.create(finance=instance, **detail)

        return instance

